/**
 * CreateTime   : 2020年8月29日
 * Des          : UI管理系统
 */

import { BaseUI } from "./BaseUI";
import { ResourceMgr } from "../ResourceMgr";
import { EnUILayer } from "../const/EnCommon";
import { Handler } from "../event/Handler";
import { instantiate, Node, Vec2, Vec3 } from "cc";
import { UIControl } from "./UIControl";
import { Utitls } from "../Utils";
export class UISystem {
    private static ui: UISystem;

    private uiPanels: Map<string, BaseUI> = new Map<string, BaseUI>();

    private uiHidePanels: Map<string, boolean> = new Map<string, boolean>();

    private uiControl: UIControl;

    private uiLoading = new Map<string, boolean>();

    private curViewPanel: string;

    private preViewPanel: Array<string> = new Array<string>();

    static get instance() {
        if (!this.ui) {
            this.ui = new UISystem();
        }

        return this.ui;
    }
    static destory() {
        if (this.ui) {
            this.ui = null;
        }
    }

    private spliteViewArray = new Array<string>();
    private whitelistForClose = new Map<string, boolean>(); // UI关闭白名单

    Init() {
        this.uiControl = new UIControl();
    }

    ShowPanel(type: string, completeCallback: Handler, args?: any[], isCtr?: boolean) {
        if (!isCtr) {
            this.Show(type, completeCallback, args, isCtr);
        }
        else {
            this.uiControl.Show(type, args, isCtr);
        }
    }

    ShowTopPanel(type: string, completeCallback: Handler, args?: any[]) {
        this.Show(type, completeCallback, args, false, EnUILayer.Top);
    }

    ShowFreePanel(type: string, completeCallback: Handler, args?: any[]) {
        this.Show(type, completeCallback, args, false, EnUILayer.Free);
    }

    ShowBottomPanel(type: string, completeCallback: Handler, args?: any[])
    {
        this.Show(type, completeCallback, args, false, EnUILayer.Bottom);
    }

    Show(type: string, completeCallback: Handler, args?: any[], isCtr?: boolean, layar?: EnUILayer) {
        if (this.uiPanels.has(type)) {
            this.uiPanels.get(type).Show(args);
        }
        else {
            this.ShowPanelAsync(type, completeCallback, args, isCtr, layar);
        }
        if (this.CheckPanel(type)) {
            let prePanel = this.curViewPanel;
            this.preViewPanel.push(prePanel);
            this.curViewPanel = type;
        }
    }

    IsShow(type: string)
    {
        if (this.uiPanels.has(type)) {
            return true;
        }
        return false;
    }

    HidePanel(type: string) {
        if (this.uiPanels.get(type)) {
            this.uiPanels.get(type).Hide();
        }
        else {
            this.uiHidePanels.set(type, true);
        }

        if (this.curViewPanel == type) {
            this.curViewPanel = this.preViewPanel.pop();
        }
        else {
            let index = this.preViewPanel.indexOf(type);
            if (index != -1) {
                this.preViewPanel.splice(index, 1);
            }
        }
    }

    CloseAllCtrPanel() {
        this.uiControl.CloseAll();
    }

    CloseAllPanel() {
        this.uiPanels.forEach((value, _) => {
            value.Close();
        })

        this.uiPanels.clear();
    }

    ClosePanelsNotWhitelist() {
        let del = []
        this.uiPanels.forEach((value, key) => {
            if (!this.whitelistForClose.has(key)) {
                value.Close();
                del.push(key);
            }
        })
        for (let index = 0; index < del.length; index++) {
            const element = del[index];
            this.uiPanels.delete(element);
        }
    }

    DestroyPanel(type?: string) {
        if (!type) {
            this.uiControl.Close()
        }
        else {
            if (this.uiControl.IsHave(type)) {
                this.uiControl.Close(type)
            }
            else {
                this.Destroy(type);
            }
        }
        if (this.curViewPanel == type) {
            this.curViewPanel = this.preViewPanel.pop();
        }
        else {
            let index = this.preViewPanel.indexOf(type);
            if (index != -1) {
                this.preViewPanel.splice(index, 1);
            }
        }
    }

    Destroy(type: string) {
        if (this.uiPanels.get(type)) {
            let basePanel = this.uiPanels.get(type);
            basePanel.Hide();
            if (basePanel.node) {
                basePanel.node.removeFromParent();
                basePanel.node.destroy();
            }
            this.uiPanels.delete(type);
        }
    }

    CheckPanelIsClosed(type: string) {
        if (this.uiPanels.get(type)) {
            return false;
        }
        return true;
    }

    CheckPanelIsHided(type: string) {
        if (this.uiPanels.get(type)) {
            return !this.uiPanels.get(type).node.active
        }
        return true
    }

    //当前显示面板
    CurShowPanel() {
        return this.curViewPanel;
    }

    // 异步加载
    private ShowPanelAsync(type: string, completeCallback: Handler, args: any[], isCtr?: boolean, layer = EnUILayer.Normal) {
        if (this.uiLoading.has(type)) {
            return;
        }
        let myThis = this;
        this.uiLoading.set(type, true);
        ResourceMgr.instance.LoadUIPrefab(type, Handler.create(function (res: Node) {
            let basePanel = res.getComponent(BaseUI);
            if (basePanel) {
                basePanel.isCtr = isCtr;
                myThis.uiPanels.set(type, basePanel);
                basePanel.SetLayer(layer);
                basePanel.Awake();
                basePanel.Show(args);
                
                // console.log(type,now2-now1);
                myThis.uiLoading.delete(type);
                if (myThis.uiHidePanels.has(type)) {
                    if (myThis.uiHidePanels.get(type)) {
                        myThis.uiHidePanels.delete(type);
                        basePanel.Hide();
                    }
                }
                if (completeCallback) {
                    completeCallback.run();
                }
            }
        }.bind(this), this));
    }

    // 检查不需要记录面板
    private CheckPanel(type: string) {
        let result = false;
        if (this.spliteViewArray.indexOf(type) == -1 && this.preViewPanel.indexOf(type) == -1 && this.curViewPanel != type) {
            result = true;
        }
        return result;
    }

    public Add2Whitelist(type: string) {
        this.whitelistForClose.set(type, true);
    }

    public RemoveFromWhitelist(type: string) {
        this.whitelistForClose.delete(type);
    }
}